package com.iceengine.j3d.particles;

/**
 * The particle emitter for the particle engine.
 * @author penguin
 */
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.util.Color;
import org.lwjgl.opengl.GL11;

import java.util.Random;

import com.iceengine.j3d.objects.IObject;

public class ParticleEmitter implements IObject{
    private Vector3f position;
    private Vector3f Rotation;
    private Vector3f Gravitation;
    private int particleLifetime;
    private Color myColor;
    private Particle[] Particles;
    private Vector3f moveTo;
    private boolean GenerateLifetime;
    private boolean repeat;

    public void drawObject(Vector3f theTranslation, Vector3f rotation)
    {
        Update();
        drawParticles();
    }

    public void rotateX(float angle)
    {
        Rotation.x = angle;
    }

    public void rotateY(float angle)
    {
        Rotation.y = angle;
    }

    public void rotateZ(float angle)
    {
        Rotation.z = angle;
    }

    /**
     * ParticleEmitter constructor
     * @param Position Position of the emitter
     * @param MoveTo Particles move in axes (Vector3f)
     * @param color Particles color
     * @param lifetime Particle's lifetime
     * @param particles Number of particles
     * @param generateLifetime should lifetime get generated?
     * @param Repeat Repeat everytime from 0 or spawn particles anytime?
     */
    public ParticleEmitter(Vector3f Position,Vector3f MoveTo,Vector3f gravitation, Color color, int lifetime, int particles, boolean generateLifetime, boolean Repeat)
    {
        Gravitation = gravitation;
        repeat = Repeat;
        GenerateLifetime = generateLifetime;
        moveTo = MoveTo;
        position = Position;
        myColor = color;
        particleLifetime = lifetime;

        Rotation = new Vector3f(0,0,0);

        Particles = new Particle[particles];


        Random generator = new Random();

        for(int i = 0; i < particles; i++)
        {
            Particles[i] = createParticle();
        }
    }
    /**
     * Updates the particles.
     */
    public void Update()
    {
        for(int i = 0; i < Particles.length; i++)
        {
            Particles[i].Update();
            if(!Particles[i].isParticleAlive())
            {
                if(repeat)
                Particles[i] = createParticle();
            }
        }
    }
    /**
     * Creates a particle with the values given in the constructor.
     * @return A new particle.
     */
    private Particle createParticle()
    {
        float V = (float)(Math.random() * 25);
        float angle = (float)(Math.random() * 360);
        Vector3f velocity = new Vector3f();

        velocity.x = (float)Math.sin(angle) * V * moveTo.x;
        velocity.y = (float)Math.cos(angle) * V * moveTo.y;
        velocity.z = (((float)Math.random() * 10) - 5) / 10 * V * moveTo.z;//generator.nextFloat() % 10)-5) / 10 * V;
        //System.out.println("NEW " + " " + position.x + " " + position.y + " " + position.z + " " + angle + " " + V + " " + velocity.x + " " + velocity.y + " " + velocity.z);
        int life = 0;
        if(GenerateLifetime)
        {
            life = (int)(Math.random() * particleLifetime);
        } else {
            life = particleLifetime;
        }

        return new Particle(life,new Vector3f(Gravitation.x, Gravitation.y, Gravitation.z), new Vector3f(position.x, position.y, position.z),velocity, myColor);
    }
    /**
     * Draws the particles to the screen.
     */
    public void drawParticles()
    {
        GL11.glDisable(GL11.GL_TEXTURE_2D);
        GL11.glBegin(GL11.GL_POINT);

        for(int i = 0; i < Particles.length; i++)
        {
            Particles[i].drawParticle();
        }
        
        GL11.glEnd();
        GL11.glEnable(GL11.GL_TEXTURE_2D);

        GL11.glColor4f(1,1,1,1);
    }
    /**
     * Tests if work for every particle is done.
     * @return True if the work is done, false if there are any particles alive.
     */
    public boolean isWorkDone()
    {
        boolean workDone = false;
        for(int i = 0; i < Particles.length; i++)
        {
            if(!Particles[i].isParticleAlive())
                workDone = true;
        }
        return workDone;
    }
}
